package com.zw.syncopenapi.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * VivoApiUtil -
 * Created by Jack on 2025/7/31.
 * Description:
 */
@Service
public class VivoApiUtil {

    // 配置专用OkHttpClient
    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)  // 连接超时
            .readTimeout(60, TimeUnit.SECONDS)     // 读取超时
            .writeTimeout(60, TimeUnit.SECONDS)    // 写入超时
            .retryOnConnectionFailure(true)        // 自动重试
            .build();


    /***
     *  vivo openapi 请求地址
     * */
    private static final String VIVO_OPENAPI_URL = "https://marketing-api.vivo.com.cn/openapi";



    public String post(String url,String advertiserId, String accessToken,String jsonStr) throws IOException {
        String nonce = UUID.randomUUID().toString().replace("-", "");
        String timestamp =String.valueOf(System.currentTimeMillis());
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, jsonStr);
        Request request = new Request.Builder()
                .url(VIVO_OPENAPI_URL+url + "?access_token=" + accessToken + "&timestamp=" + timestamp + "&nonce=" + nonce + "&advertiser_id=" + advertiserId)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        Response response = client.newCall(request).execute();
        return response.body().string();
    }

    public String get(String url, String advertiserId, String accessToken) throws IOException {
        // 生成随机数和时间戳
        String nonce = UUID.randomUUID().toString().replace("-", "");
        String timestamp = String.valueOf(System.currentTimeMillis());

        // 构建基础URL
        HttpUrl.Builder urlBuilder = HttpUrl.parse(VIVO_OPENAPI_URL + url).newBuilder()
                .addQueryParameter("access_token", accessToken)
                .addQueryParameter("timestamp", timestamp)
                .addQueryParameter("nonce", nonce)
                .addQueryParameter("advertiser_id", advertiserId);


        // 构建请求
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        Request request = new Request.Builder()
                .url(urlBuilder.build())
                .get()
                .addHeader("Content-Type", "application/json")
                .build();

        // 执行请求
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

    public String uploadVideo(String filePath, String advertiserId, String accessToken) throws IOException {
        // 重试配置
        int maxRetries = 3;
        long retryInterval = 2000; // 2秒间隔
        int retryCount = 0;
        IOException lastException = null;

        while (retryCount <= maxRetries) {
            try {
                // 生成随机参数
                String nonce = UUID.randomUUID().toString().replace("-", "");
                String timestamp = String.valueOf(System.currentTimeMillis());

                // 准备文件（每次重试都重新读取）
                File file = new File(filePath);
                if (!file.exists()) {
                    throw new IOException("文件不存在: " + filePath);
                }

                // 构建请求体
                RequestBody fileBody = RequestBody.create(
                        MediaType.parse("application/octet-stream"),
                        file
                );

                MultipartBody body = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("file", file.getName(), fileBody)
                        .build();

                // 构建URL
                HttpUrl url = new HttpUrl.Builder()
                        .scheme("https")
                        .host("marketing-api.vivo.com.cn")
                        .addPathSegments("openapi/v1/upload/file/video")
                        .addQueryParameter("access_token", accessToken)
                        .addQueryParameter("timestamp", timestamp)
                        .addQueryParameter("nonce", nonce)
                        .addQueryParameter("advertiser_id", advertiserId)
                        .build();

                // 执行请求
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .addHeader("Content-Type", "multipart/form-data")
                        .build();

                try (Response response = client.newCall(request).execute()) {
                    if (!response.isSuccessful()) {
                        throw new IOException("HTTP请求失败: " + response.code());
                    }

                    String responseBody = response.body().string();
                    // 检查业务状态码
                    JSONObject json = JSON.parseObject(responseBody);
                    if (json.getInteger("code") != 0) {
                        throw new IOException("业务处理失败: " + json.getString("message"));
                    }

                    return responseBody;
                }
            } catch (IOException e) {
                lastException = e;
                retryCount++;

                if (retryCount <= maxRetries) {
                    try {
                        Thread.sleep(retryInterval * retryCount); // 指数退避
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new IOException("重试被中断", ie);
                    }
                }
            }
        }
        throw new IOException(String.format("上传失败（重试%d次后）: %s", maxRetries, lastException.getMessage()), lastException);
    }


    /**
     * DMP人群包文件上传接口
     * @param filePath 人群包文件路径（txt/zip/xlsx/xls）
     * @param advertiserId 广告主ID
     * @param accessToken 访问令牌
     * @return 接口响应JSON字符串
     * @throws IOException 上传失败时抛出
     */
    public String uploadDmpTagFile(String filePath, String advertiserId, String accessToken) throws IOException {
        // 1. 参数校验
        File file = new File(filePath);
        if (!file.exists()) {
            throw new IOException("文件不存在: " + filePath);
        }
        if (file.length() > 100 * 1024 * 1024) {
            throw new IOException("文件大小超过100MB限制");
        }

        // 2. 计算文件MD5
        String fileMd5;
        try {
            fileMd5 = calculateFileMD5(file);
        } catch (NoSuchAlgorithmException e) {
            throw new IOException("MD5计算失败", e);
        }

        // 3. 构建请求
        String nonce = UUID.randomUUID().toString().replace("-", "");
        String timestamp = String.valueOf(System.currentTimeMillis());

        RequestBody fileBody = RequestBody.create(
                MediaType.parse("application/octet-stream"),
                file
        );

        MultipartBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(), fileBody)
                .addFormDataPart("md5", fileMd5)
                .build();

        HttpUrl url = new HttpUrl.Builder()
                .scheme("https")
                .host("marketing-api.vivo.com.cn")
                .addPathSegments("openapi/v1/ad/dmpTag/upload")
                .addQueryParameter("access_token", accessToken)
                .addQueryParameter("timestamp", timestamp)
                .addQueryParameter("nonce", nonce)
                .addQueryParameter("advertiser_id", advertiserId)
                .build();

        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .addHeader("Content-Type", "multipart/form-data")
                .build();

        // 4. 执行请求（带重试机制）
        int maxRetries = 3;
        int retryCount = 0;
        IOException lastException = null;

        while (retryCount <= maxRetries) {
            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("HTTP请求失败: " + response.code());
                }

                String responseBody = response.body().string();
                JSONObject json = JSON.parseObject(responseBody);
                if (json.getInteger("code") != 0) {
                    throw new IOException("业务处理失败: " + json.getString("message"));
                }
                return responseBody;
            } catch (IOException e) {
                lastException = e;
                if (retryCount++ < maxRetries) {
                    try {
                        Thread.sleep(2000 * retryCount); // 指数退避
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new IOException("重试被中断", ie);
                    }
                }
            }
        }
        throw new IOException(String.format("上传失败（重试%d次后）", maxRetries), lastException);
    }

    /**
     * 计算文件MD5值（辅助方法）
     */
    private String calculateFileMD5(File file) throws IOException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        try (InputStream is = new FileInputStream(file)) {
            byte[] buffer = new byte[8192];
            int len;
            while ((len = is.read(buffer)) != -1) {
                md.update(buffer, 0, len);
            }
        }
        byte[] digest = md.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
